 /*********************************  Barbing Tab - now the Dark Forest Tab ***********************************/
Tabs.Barb = {
  tabLabel: unsafeWindow.g_js_strings.commonstr.darkForest,
  tabOrder : 125,
  myDiv : null,
  MapAjax : new CMapAjax(),
  popFirst : true,
  opt : {},
  nextattack : null,
  searchRunning : false,
  tilesSearched : 0,
  tilesFound : 0,
  curX : 0,
  curY : 0,
  lastX : 0,
  firstX : 0,
  firstY : 0,
  lastY : 0,
  rallypointlevel:0,
  knt:{},
  barbArray:{},
  lookup:1,
  city:1,
  deleting:false,
  maplag:0,
  troopDef : [
      ['Supply', 1],
      ['Miltia', 2],
      ['Scout', 3],
      ['Pikes', 4],
      ['Swords', 5],
      ['Archers', 6],
      ['Cavalry', 7],
      ['Heavies', 8],
      ['Wagons', 9],
      ['Balls', 10],
      ['Rams', 11],
      ['Cats', 12],
      ['BThorn', 13],
      ['EXec', 14],
      ['Tower', 15],
     ],
    
  init : function (div){
    var t = Tabs.Barb;
    if(Options.dfbtns)AddSubTabLink(unsafeWindow.g_js_strings.commonstr.darkForest,t.toggleBarbState, 'DFToggleTab');
    t.myDiv = div;
    setInterval(t.sendreport, 1*60*1000);
 
    var m = '<DIV id=pbTowrtDivF class=pbStat>AUTOMATED FOREST FUNCTION</div><TABLE id=pbbarbingfunctions width=100% height=0% class=pbTab><TR align="center">';
     if (AttackOptions.Running == false) {
           m += '<TD><INPUT id=AttSearch type=submit value="Attack = OFF"></td>';
           if(document.getElementById('DFToggleTab'))document.getElementById('DFToggleTab').innerHTML = '<span style="color: #CCC">'+unsafeWindow.g_js_strings.commonstr.darkForest+': Off</span>';
       } else {
           m += '<TD><INPUT id=AttSearch type=submit value="Attack = ON"></td>';
            if(document.getElementById('DFToggleTab'))document.getElementById('DFToggleTab').innerHTML = '<span style="color: #FFFF00">'+unsafeWindow.g_js_strings.commonstr.darkForest+': On</span>';
       }
      m += '<TD><INPUT id=troopselect type=submit value="Select troops"></td>';
      m += '<TD><INPUT id=Options type=submit value="Options"></td>';
      m += '</tr></table></div>';
      
      m += '<DIV id=pbTraderDivD class=pbStat>FOREST STATS</div>';
    
      m += '<TABLE id=pbbarbstats width=95% height=0% class=pbTab><TR align="left"><TR>';
      for(i=0;i<Seed.cities.length;i++){
              m += '<TD>' + Seed.cities[i][1] +'</td>';
      }
      m+='</tr><TR>';
      for(i=0;i<Seed.cities.length;i++){
              m += '<TD><DIV><span id='+ 'pdtotalcity' + i +'></span></div></td>';
      }
      m+='</tr><TR>';
      for(i=0;i<Seed.cities.length;i++){
              m += '<TD><DIV><span id='+ 'pddatacity' + i +'></span></div></td>';
      }
      m+='</tr><TR>'
       for(i=0;i<Seed.cities.length;i++){
              m += '<TD><DIV><span id='+ 'pddataarray' + i +'></span></div></td>';
     }
     m+='</tr></table><TABLE id=pbbarbstats width=95% height=0% class=pbTab><TR align="left"><TR>';
     for (i=0;i<=6;i++) {
         m+='<TD><DIV><span id='+ 'pberror' + i +'></span></div></td>';
     }
     m+='</tr></table>';
     m += '<DIV id=pbTraderDivD class=pbStat>FOREST OPTIONS</div>';
     m += '<TABLE width=95% height=0% class=ptTab><TR align="left">';
     for(i=0;i<Seed.cities.length;i++){
        m += '<TR><TD>' + Seed.cities[i][1] +'</td>';
        for (w=1;w<=10;w++){
           m += '<TD class=pblevelopt><INPUT id=pbcity'+i+'level'+w+' type=checkbox unchecked=true>Lvl:'+w+'</td>';
        }
     }
     m+='</table>'
     m+='<div id="dferrorlog"></div>';
     t.myDiv.innerHTML = m;

     saveAttackOptions();
     t.checkBarbData();

     for(i=0;i<Seed.cities.length;i++){
        var element = 'pdtotalcity'+i;
        if (t.barbArray[i+1] == undefined) document.getElementById(element).innerHTML = 'No Data';
        else document.getElementById(element).innerHTML =  'Forests:' + t.barbArray[i+1].length;
     }
    
    for(i=0;i<Seed.cities.length;i++){
        for (w=1;w<=10;w++){
            document.getElementById('pbcity'+i+'level'+w).checked = AttackOptions.Levels[i+1][w];
        }
    }
    
    document.getElementById('AttSearch').addEventListener('click', function(){t.toggleBarbState(this)} , false);
    document.getElementById('Options').addEventListener('click', t.barbOptions , false);
    document.getElementById('troopselect').addEventListener('click', t.troopOptions , false);
    var element_class = document.getElementsByClassName('pblevelopt');
    for (k=0;k<element_class.length;k++){
        element_class[k].addEventListener('click', t.saveLevelOptions , false);
    }
   },
  
  saveLevelOptions : function(){
        for(i=0;i<Seed.cities.length;i++){
            AttackOptions.Levels[i+1][0]=false;
            for (w=1;w<=10;w++){
                var ele = document.getElementById('pbcity'+i+'level'+w);
                AttackOptions.Levels[i+1][w]=ele.checked;
                if (ele.checked)                    
                    AttackOptions.Levels[i+1][0]=true;
            }        
        }
        saveAttackOptions();
   },
   
  troopOptions: function(){
       var t = Tabs.Barb;
      var troopDef = t.troopDef;
       if(t.troopselect == null)    
        t.troopselect = new pbPopup ('pbtroopselect', 0, 0, 850, 450, true, function(){t.saveTroops();});
       t.troopselect.centerMe (mainPop.getMainDiv());  
       var z= '<DIV id=pbTraderDivD class=pbStat>TROOP SELECTION</div><TABLE width=100%><TR>';
     z+='<TD></td>';
     for(var i=0; i<troopDef.length; i++)
        z+='<TD>'+troopDef[i][0]+'</td>';
     z+='<TD>MIN dist</td><TD>MAX dist</td>';
     for(i=0;i<10;i++){
         z += '<TR><TD>Level_'+(i+1)+': </td>';
         for(var j=0; j<troopDef.length; j++){
             z += '<TD><INPUT id="level'+i+'troop'+j+'" type=text size=6 maxlength=6 value="'+(AttackOptions.Troops[i+1][j+1]?AttackOptions.Troops[i+1][j+1]:0)+'" /></td>';
         }
        z+='<TD align=left><INPUT id=Mindist'+i+' type=text size=3 maxlength=3 value="'+AttackOptions.MinDistance[i+1]+'"</td>';
         z+='<TD align=right><INPUT id=dist'+i+' type=text size=3 maxlength=3 value="'+AttackOptions.Distance[i+1]+'"</td>';
         z+='</tr>';                 
     }
     z+='</table>';
      t.troopselect.getMainDiv().innerHTML = z;
      t.troopselect.show(true);
  },
  
  barbOptions: function(){
       var t = Tabs.Barb;
       if(t.barboptions == null)    
        t.barboptions = new pbPopup ('pbbarboptions', 0,0, 375,350, true);
       t.barboptions.centerMe (mainPop.getMainDiv());  
     t.barboptions.getTopDiv().innerHTML = '<CENTER><b>Dark Forest Options for server '+getServerId()+'</b></CENTER>';
      var y = '<DIV style="max-height:400px; overflow-y:auto;"><DIV class=pbStat>RESET FORESTS</div><TABLE width=100%>';
       y +='<TR><TD style="margin-top:5px; text-align:center;"><INPUT id=pbresetbarbs type=submit value="Reset Forests"></td>';
       y +='<TD style="margin-top:5px; text-align:center;"><INPUT id=pbpaintbarbs type=submit value="Show forests"></td>';
       y += '<TD><SELECT id=pbcity type=list></td></tr></table>';
       y +='<table width=100%><TD colspan=2 style="margin-top:5px; text-align:center;"><DIV class=pbStat> OPTIONS </div></td>';
     y +='<TR><TD>Attack interval: </td><td><INPUT id=pbsendint type=text size=4 maxlength=3 value='+ AttackOptions.SendInterval +' \> seconds</td></tr>';
     y +='<TR><TD>Max search distance: </td><td><INPUT id=pbmaxdist type=text size=4 maxlength=3 value='+ AttackOptions.MaxDistance +' \></td></tr>';
     y +='<TR><TD>Keep rallypoint slot(s) free: </td><Td><INPUT id=rallyclip type=text size=3 maxlength=2 value="'+AttackOptions.RallyClip+'" \> </td></tr>';
     y +='<TR><TD><INPUT id=pbreset type=checkbox '+(AttackOptions.UpdateEnabled?'CHECKED':'')+'\> Reset search every </td><td><INPUT id=pbresetint type=text size=3 maxlength=2 value='+AttackOptions.UpdateInterval+' \>minutes</td></tr>';
     y +='<TR><TD> Skip city after </td><td><INPUT id=barbstopsearch type=text size=3 value='+AttackOptions.stopsearch+' \> tries.</td></tr>';
     y +='<TR><TD>Method : </td><Td> '+htmlSelector({distance:'Closest first', level:'Highest level first', lowlevel:'Lowest level first'}, AttackOptions.Method, 'id=pbmethod')+'</td></tr>';
     y +='<TR><TD>Knight priority : </td><td>'+htmlSelector({0:'Lowest combat skill', 1:'Highest combat skill'}, AttackOptions.knightselector, 'id=barbknight')+'</td></tr>';
     y +='<tr><td>Minimum knight Combat level to send: </td><td><input id=barbMinKnight type=text size=3 value='+AttackOptions.barbMinKnight+' \></td></tr>';
     y +='<tr><td>Maximum knight Combat level to send: </td><td><input id=barbMaxKnight type=text size=3 value='+AttackOptions.barbMaxKnight+' \></td></tr>';
     y +='<tr><td>Stop hitting Dark forests when Aetherstone in city is more than: </td><td><INPUT id=pbaothreshold type=text size=7 maxlength=7 value='+ AttackOptions.threshold +' \></td></tr>';
     y +='<TD><INPUT id=pbsenddfreport type=checkbox '+ (AttackOptions.MsgEnabled?'CHECKED':'') +'\> Send DF report every ';
     y +='<INPUT id=pbsenddfreportint value='+ AttackOptions.MsgInterval +' type=text size=3 \> hours </td>';     
     y+='</table></td></tr></table>';
       t.barboptions.getMainDiv().innerHTML = y;
       t.barboptions.show(true);
    
    document.getElementById('pbcity').options.length=0;
    for (i=0;i<Seed.cities.length;i++){
        var o = document.createElement("option");
        o.text = Seed.cities[i][1]
        o.value = i+1;
        document.getElementById("pbcity").options.add(o);
    }
       
    document.getElementById('pbpaintbarbs').addEventListener('click', function(){
            t.showBarbs(document.getElementById("pbcity").value,Seed.cities[document.getElementById("pbcity").value -1][1]);
            
    },false);
    document.getElementById('pbresetbarbs').addEventListener('click', t.deletebarbs,false);
    document.getElementById('pbmethod').addEventListener('change', function(){
        AttackOptions.Method=document.getElementById('pbmethod').value;
        saveAttackOptions();
        t.checkBarbData();
    },false);
    document.getElementById('barbknight').addEventListener('change', function(){
        AttackOptions.knightselector=document.getElementById('barbknight').value;
        saveAttackOptions();
    },false);
    document.getElementById('pbreset').addEventListener('change', function(){
        AttackOptions.UpdateEnabled=document.getElementById('pbreport').checked;
        saveAttackOptions();
    },false);
    document.getElementById('pbresetint').addEventListener('change', function(){
        AttackOptions.UpdateInterval=parseInt(document.getElementById('pbresetint').value);
        saveAttackOptions();
    },false);
    document.getElementById('pbsendint').addEventListener('change', function(){
        if(parseInt(document.getElementById('pbsendint').value) <5) //Set minimum attack interval to 5 seconds
            document.getElementById('pbsendint').value = 5;
        AttackOptions.SendInterval=parseInt(document.getElementById('pbsendint').value);
        saveAttackOptions();
    },false);
    document.getElementById('pbmaxdist').addEventListener('change', function(){
        if(parseInt(document.getElementById('pbmaxdist').value) > 75)
            document.getElementById('pbmaxdist').value = 75;
        AttackOptions.MaxDistance=parseInt(document.getElementById('pbmaxdist').value);
        saveAttackOptions();
    },false);
    document.getElementById('rallyclip').addEventListener('change', function(){
        AttackOptions.RallyClip=parseInt(document.getElementById('rallyclip').value);
        saveAttackOptions();
    },false);
    
    document.getElementById('barbMinKnight').addEventListener('change', function(){
        AttackOptions.barbMinKnight=parseInt(document.getElementById('barbMinKnight').value);
        saveAttackOptions();
    },false);
    document.getElementById('barbMaxKnight').addEventListener('change', function(){
        AttackOptions.barbMaxKnight=parseInt(document.getElementById('barbMaxKnight').value);
        saveAttackOptions();
    },false);
    document.getElementById('pbaothreshold').addEventListener('change', function(){
        AttackOptions.threshold=parseInt(document.getElementById('pbaothreshold').value);
        saveAttackOptions();
    },false);
    document.getElementById('barbstopsearch').addEventListener('change', function(){
        document.getElementById('barbstopsearch').value = parseInt(document.getElementById('barbstopsearch').value)>0?document.getElementById('barbstopsearch').value:1
        AttackOptions.stopsearch=parseInt(document.getElementById('barbstopsearch').value);
        saveAttackOptions();
    },false);  
      document.getElementById('pbsenddfreport').addEventListener('change', function(){
        AttackOptions.MsgEnabled = document.getElementById('pbsenddfreport').checked;
        saveAttackOptions();
    }, false);
    document.getElementById('pbsenddfreportint').addEventListener('change', function(){
        AttackOptions.MsgInterval = parseInt(document.getElementById('pbsenddfreportint').value);
        saveAttackOptions();
    }, false);      
  },
  
    showBarbs: function (citynumber,cityname) {
        var t = Tabs.Barb;
        var popTradeRoutes = null;
        t.popTradeRoutes = new pbPopup('pbShowBarbs', 0, 0, 500, 500, true, function() {clearTimeout (1000);});
        var m = '<DIV style="max-height:460px; height:460px; overflow-y:auto"><TABLE align=center cellpadding=0 cellspacing=0 width=100% class="pbShowBarbs" id="pbBars">';       
        t.popTradeRoutes.getMainDiv().innerHTML = '</table></div>' + m;
        t.popTradeRoutes.getTopDiv().innerHTML = '<TD><B>Dark Forests for city: '+cityname+'</td>';
        t.paintBarbs(citynumber,cityname);
        t._addTabHeader(citynumber,cityname);
        t.popTradeRoutes.show(true)    ;
     },
      paintBarbs: function(i,cityname){
            var t = Tabs.Barb;
                for (k=(t.barbArray[i].length-1);k>=0;k--){t._addTab(i,cityname,k+1,t.barbArray[i][k]['x'], t.barbArray[i][k]['y'],t.barbArray[i][k]['dist'], t.barbArray[i][k]['level']);}
        },
      
  _addTab: function(citynumber,cityname,queueId,X,Y,dist,level){
     var t = Tabs.Barb;
     var row = document.getElementById('pbBars').insertRow(0);
     row.vAlign = 'top';
     row.insertCell(0).innerHTML = queueId;
     row.insertCell(1).innerHTML = X;
     row.insertCell(2).innerHTML = Y;
     row.insertCell(3).innerHTML = dist;
     row.insertCell(4).innerHTML = level;
     row.insertCell(5).innerHTML = '<a class="button20" id="barbdel_' + queueId + '"><span>Delete</span></a>';
     document.getElementById('barbdel_' + queueId).addEventListener('click', function(){
        t.deleteBarbElement(citynumber,queueId,cityname, true);
     }, false);
  },
     
  _addTabHeader: function(citynumber,cityname) {
     var t = Tabs.Barb;
     var row = document.getElementById('pbBars').insertRow(0);
     row.vAlign = 'top';
     row.insertCell(0).innerHTML = "City";
     row.insertCell(1).innerHTML = "X";
     row.insertCell(2).innerHTML = "Y";
     row.insertCell(3).innerHTML = "Dist.";
     row.insertCell(4).innerHTML = "Level";
     row.insertCell(5).innerHTML = '<a class="button20" id="barbdelAll"><span>Delete ALL</span></a>';
     document.getElementById('barbdelAll').addEventListener('click', function(){
        t.deleteBarbsCity(citynumber,cityname);
     }, false);
  },   
       
  deleteBarbElement: function(citynumber,queueId,cityname,showFlag){
      var t = Tabs.Barb;
      var queueId = parseInt(queueId);
      var myarray = t.barbArray[citynumber];
      if (myarray) {
        myarray.splice((queueId-1), 1);
        GM_setValue('DF_' + Seed.player['name'] + '_city_' + citynumber + '_' + getServerId(), JSON2.stringify(myarray));
        t.checkBarbData();
        if (showFlag) t.showBarbs(citynumber,cityname);
      }
      else
      {
          //logit("not found");
      }
  },
      
  deleteBarbsCity: function(citynumber,cityname){
      var t = Tabs.Barb;
      var queueId = parseInt(queueId);
      AttackOptions.Update[citynumber][1] = 0;
      GM_deleteValue('DF_' + Seed.player['name'] + '_city_' + citynumber + '_' + getServerId())
      t.checkBarbData();
      t.showBarbs(citynumber,cityname);
      //reloadKOC();
  },  
  
  saveTroops: function(){
      var t = Tabs.Barb;
    for(i=0;i<10;i++){
           for (w=0;w<t.troopDef.length;w++){
               AttackOptions.Troops[i+1][w+1] = parseIntNan(document.getElementById('level'+i+'troop'+w).value);
           }
        if(parseIntNan(document.getElementById('dist'+i).value) > AttackOptions.MaxDistance)
            document.getElementById('dist'+i).value = AttackOptions.MaxDistance;
        AttackOptions.MinDistance[i+1] = parseIntNan(document.getElementById('Mindist'+i).value);
           AttackOptions.Distance[i+1] = parseIntNan(document.getElementById('dist'+i).value);             
     }
     saveAttackOptions();
  },
  
   deletebarbs: function(){
    for (i=1;i<=Seed.cities.length;i++){
        AttackOptions.Update[i][1] = 0;
        GM_deleteValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId())
    }
    //reloadKOC();
   },

  checkBarbData: function(){
      var t = Tabs.Barb;
    if(!AttackOptions.Running) return;
      for (i=1;i<=Seed.cities.length;i++){
      
        // if(GM_getValue('Barbs_' + Seed.player['name'] + '_city_' + i + '_' + getServerId())) //Remove old auto barb data
            // GM_deleteValue('Barbs_' + Seed.player['name'] + '_city_' + i + '_' + getServerId());
      
        if (!AttackOptions.Levels[i][0]) continue; //Skip city if not selected
        
        t.barbArray[i] = [];
          var myarray = JSON2.parse(GM_getValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId(),"[]"));
        
        if ((myarray == undefined || myarray.length == 0) && t.searchRunning==false) {
              t.lookup=i;
            if(parseInt(AttackOptions.Update[t.lookup][1]) >= parseInt(AttackOptions.stopsearch)) continue; //Skip if search results are empty more than X times
            t.searchRunning = true;
              t.opt.startX = parseInt(Seed.cities[(i-1)][2]);
              t.opt.startY = parseInt(Seed.cities[(i-1)][3]);  
              t.clickedSearch();
            break;
          }
        if (myarray){
            if(AttackOptions.Method == 'distance') t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['dist'];b = b['dist'];return a == b ? 0 : (a < b ? -1 : 1);});
            if(AttackOptions.Method == 'level') t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['level']+a['dist'];b = b['level']+b['dist'];return a == b ? 0 : (a > b ? -1 : 1);});
            if(AttackOptions.Method == 'lowlevel') t.barbArray[i] = myarray.sort(function sortBarbs(a,b) {a = a['level']+a['dist'];b = b['level']+b['dist'];return a == b ? 0 : (a < b ? -1 : 1);});
              GM_setValue('DF_' + Seed.player['name'] + '_city_' + i + '_' + getServerId(), JSON2.stringify(t.barbArray[i]));
          }
        AttackOptions.Update[i][1] = 0;
        saveAttackOptions();
      }
      t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3000)+2000));
  },
  
  toggleBarbState: function(obj){
     obj = document.getElementById('AttSearch');
    var t = Tabs.Barb;
    if (AttackOptions.Running == true) {
        AttackOptions.Running = false;
        obj.value = "Attack = OFF";
        if(document.getElementById('DFToggleTab'))document.getElementById('DFToggleTab').innerHTML = '<span style="color: #CCC">'+unsafeWindow.g_js_strings.commonstr.darkForest+': Off</span>';
        saveAttackOptions();
        t.nextattack = null;
    } else {
        AttackOptions.Running = true;
        obj.value = "Attack = ON";
        if(document.getElementById('DFToggleTab'))document.getElementById('DFToggleTab').innerHTML = '<span style="color: #FFFF00">'+unsafeWindow.g_js_strings.commonstr.darkForest+': On</span>';
        saveAttackOptions();
        t.checkBarbData();
        t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3000)+2000));
    }
  },
  
  barbing : function(){
       var t = Tabs.Barb;
       var city = t.city;
       citynumber = Seed.cities[city-1][0];
       cityID = 'city' + citynumber;
       t.getAtkKnight(cityID);
       var slots = getFreeMarchSlots(citynumber);
      
      //Only send DF if city is not over 750K astone:: rewritten I want df's to farm items and level knights.. who cares about aetherstone?  -baos
      if (Seed.resources[cityID]["rec5"][0] > Number(AttackOptions.threshold)) 
      {
         logit("DF: too much resource in city");
         return;
      };
       var element1 = 'pddatacity'+(city-1);
       document.getElementById(element1).innerHTML = 'Sent: ' + AttackOptions.BarbsDone[city];
       var element2 = 'pddataarray'+(city-1);
       document.getElementById(element2).innerHTML =  'RP: (' + slots + '/' + getMaxMarches(citynumber) +')';
       if (Number(slots) <= Number(AttackOptions.RallyClip)) 
       {
         logit("DF: no free slots");
         return;
       }
       
       if (t.knt.toSource() == "[]") 
       {
         logit("DF: no free knight");
         return;
       }
       var kid = t.knt[0].ID;
       
       if(t.barbArray[city] && t.barbArray[city].length > 0)
       {
        var barbinfo = t.barbArray[city].shift();
       }
       else if(parseInt(AttackOptions.Update[city][1])==0)
       {
        if(!t.searchRunning)
        {
          t.checkBarbData();
        }
        logit("DF: update == 0");
        return;
       } else {
        logit("DF: other return?");
        return;
       }
       var check=0;
       var barblevel = parseInt(barbinfo.level);
        
        if (AttackOptions.Levels[city][barbinfo.level])
            check=1;
        
        if (barbinfo.dist < AttackOptions.MinDistance[barblevel] || barbinfo.dist > AttackOptions.Distance[barblevel])
        {
            check=0;
            GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
            logit("DF: barbinfo.dist return");
            return;
        }

         // check troop levels in city
         var trps = AttackOptions.Troops[barblevel];
         var num_troops = 0;
         for (var ii=1; ii<16; ii++) 
         {
            if (parseInt(trps[ii]) > Seed.units[cityID]['unt'+ii]) check = 0;
            num_troops += trps[ii];
         }
         if (num_troops == 0) check = 0;
         
       if (check == 0){
        t.barbArray[city].push(barbinfo);
        GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
        logit("DF: not enough troops");
        return;
       }
       
       var element = 'pdtotalcity'+(city-1);
        if (t.barbArray[city] == undefined) document.getElementById(element).innerHTML = 'No Data';
        else document.getElementById(element).innerHTML =  'Forests:' + t.barbArray[city].length;
       
       var xcoord = barbinfo['x'];
       var ycoord = barbinfo['y'];
       t.doBarb(citynumber,city,xcoord,ycoord,barblevel,kid,trps);
       saveAttackOptions();
  },

  getnextCity: function(){
    var t = Tabs.Barb;
    if(!AttackOptions.Running) return;
    
    var city = t.city+1;
    if (city>Seed.cities.length){
        city=1;
    }
    t.city = city;
    if(AttackOptions.UpdateEnabled){
        var now = unixTime();
        if(now > parseInt(AttackOptions.Update[city][0] + (AttackOptions.UpdateInterval*60))){
            AttackOptions.Update[city][1]=0;
            t.barbArray[city] = []; //Clears data if last update was more than X minutes
            GM_setValue('DF_' + Seed.player['name'] + '_city_' + city + '_' + getServerId(), JSON2.stringify(t.barbArray[city]));
        }
    }
    
    if(AttackOptions.Levels[city][0]){
        t.barbing();
        t.nextattack = setTimeout(t.getnextCity, parseInt((Math.random()*3)+AttackOptions.SendInterval)*1000);
    } else {
        t.getnextCity();
    }
        
  },
  
  getAtkKnight : function(cityID)
  {
    var t = Tabs.Barb;
    t.knt = new Array();
    
    for (k in Seed.knights[cityID])
    {
      var knight = Seed.knights[cityID][k];
      var level = parseInt(Math.sqrt(parseInt(knight.experience) / 75)) + 1;
      var unpoints = level - parseInt(knight.skillPointsApplied);
      var cityLeaders = Seed.leaders[cityID];
      
      if ( knight.knightStatus == 1 && 
           cityLeaders.resourcefulnessKnightId != knight.knightId && 
           cityLeaders.politicsKnightId != knight.knightId && 
           cityLeaders.combatKnightId != knight.knightId && 
           cityLeaders.intelligenceKnightId != knight.knightId && 
           knight.combat >= AttackOptions.barbMinKnight && 
           (parseInt(knight.combat) + parseInt(unpoints)) <= AttackOptions.barbMaxKnight) 
      {
        t.knt.push ({
          Name:   knight.knightName,
          Combat: knight.combat,
          ID:   knight.knightId,
        });
      }
    }
    
    t.knt = t.knt.sort(function sort(a,b) 
    {
      a = parseInt(a['Combat']);
      b = parseInt(b['Combat']);
      
      if(parseInt(AttackOptions.knightselector) > 0)
        return a == b ? 0 : (a > b ? -1 : 1);
      else
        return a == b ? 0 : (a < b ? -1 : 1);
    });
  },
    
  doBarb: function(cityID,counter,xcoord,ycoord,level,kid,trps){
          var t = Tabs.Barb;
          var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
          params.cid=cityID;
          params.type=4;
          params.kid=kid;
          params.xcoord = xcoord;
          params.ycoord = ycoord;
          logit("DF: dobarb");
        for (ii=1; ii<parseInt(t.troopDef.length+1); ii++) {
			if(parseInt(trps[ii]) > Seed.units['city'+cityID]['unt'+ii]){
				document.getElementById('dferrorlog').innerHTML = '<FONT color=red>'+Cities.byID[cityID].name+' dark forest failed: Not doing march, not enough units </FONT>';
				return;
			};
            if(parseInt(trps[ii]) > 0)
                params['u'+ii]=trps[ii];
        };
		if (parseInt(trps[ii]) > Seed.units['city'+cityID]['unt'+ii]) check = 0;

          AttackOptions.BarbsTried++;
          document.getElementById('pberror1').innerHTML = 'Tries:'+ AttackOptions.BarbsTried;
          
    var profiler = new CM.Profiler("ResponseTime", "march.php");
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/march.php" + unsafeWindow.g_ajaxsuffix, 
    {
      method: "post",
      parameters: params,
      loading: true,

      onSuccess: function (transport) 
      {
        profiler.stop();
        var rslt = eval("(" + transport.responseText + ")");
        
           if(rslt.ok) {
                     AttackOptions.BarbsDone[counter]++;
                     var element1 = 'pddatacity'+(counter-1);
                     document.getElementById(element1).innerHTML = 'Sent: ' + AttackOptions.BarbsDone[counter];
                     var element2 = 'pddataarray'+(counter-1);
               document.getElementById(element2).innerHTML =  'RP: (' + March.getMarchSlots(cityID) + '/' + March.getTotalSlots(cityID) +')';
                     GM_setValue('DF_' + Seed.player['name'] + '_city_' + counter + '_' + getServerId(), JSON2.stringify(t.barbArray[counter]));
                     saveAttackOptions();
                   } else {
					   if(rslt.error_code && rslt.msg)document.getElementById('dferrorlog').innerHTML = '<FONT color=red>'+Cities.byID[cityID].name+' dark forest failed: '+rslt.msg+'</FONT>';
                     //logit( inspect(rslt,3,1));
                     if (rslt.error_code != 8 && rslt.error_code != 213 && rslt.error_code == 210) AttackOptions.BarbsFailedVaria++;
                     if (rslt.error_code == 213)AttackOptions.BarbsFailedKnight++;
                     if (rslt.error_code == 210) AttackOptions.BarbsFailedRP++;
                     if (rslt.error_code == 4) actionLog('not enough units to attack darkforest');
                     if (rslt.error_code == 8) {
						 AttackOptions.BarbsFailedTraffic++;
						 t.doBarb(cityID,counter,xcoord,ycoord,level,kid,trps);
						 return;
					 }
                     if (rslt.error_code == 104) {
                       AttackOptions.BarbsFailedBog++;
                       GM_setValue('DF_' + Seed.player['name'] + '_city_' + counter + '_' + getServerId(), JSON2.stringify(t.barbArray[counter]));
                       saveAttackOptions();
                     }
                     document.getElementById('pberror2').innerHTML = 'Excess Traffic errors:' + AttackOptions.BarbsFailedTraffic;
                     document.getElementById('pberror3').innerHTML = 'Rally Point errors: '+ AttackOptions.BarbsFailedRP;
                     document.getElementById('pberror4').innerHTML = 'Knight errors:' + AttackOptions.BarbsFailedKnight;
                     document.getElementById('pberror5').innerHTML = 'Other errors:' + AttackOptions.BarbsFailedVaria;
                     document.getElementById('pberror6').innerHTML = 'Bog errors:' + AttackOptions.BarbsFailedBog;
                     //unsafeWindow.Modal.showAlert(printLocalError((rslt.error_code || null), (rslt.msg || null), (rslt.feedback || null)))
                     }
      },
      
      onFailure: function () 
      {
        profiler.stop();
      }
    });

  },
  
  sendreport: function(){
    var t = Tabs.Barb;
    if(!AttackOptions.MsgEnabled) return;
    if(!AttackOptions.Running) return;
    
    var now = new Date().getTime()/1000.0;
    now = now.toFixed(0);
    if (now < (parseInt(AttackOptions.LastReport)+(AttackOptions.MsgInterval*60*60))) return;
    
    var total = 0;
    var params = unsafeWindow.Object.clone(unsafeWindow.g_ajaxparams);
    params.emailTo = Seed.player['name'];
    params.subject = "AutoDF Overview";
    var message = 'AutoDF Stats:' + '%0A';
    
      message += '%0A Aetherstone Gain (for '+ AttackOptions.MsgInterval +' hour(s) of DF hunting) %0A';
      var totaldf = 0;
    for (q=1;q<=Seed.cities.length;q++){
        var cityID = 'city' + Seed.cities[q-1][0];
        totaldf += Number(AttackOptions.BarbsDone[q]);
        message+= Seed.cities[q-1][1] + ': ' + AttackOptions.BarbsDone[q] + ' attacks on ' + t.barbArray[q].length +' forests' + '%0A';        
  		  var gain = parseInt(Seed.resources[cityID]['rec5'][0] ) - AttackOptions.AetherStatus[q];
        message+= Seed.cities[q-1][1] + ': Start: ' + addCommas(AttackOptions.AetherStatus[q]) + ' End :' + addCommas(parseInt(Seed.resources[cityID]['rec5'][0] )) + ' Gain: ';
        message += addCommas(gain)  + '%0A';
        total += gain;
        AttackOptions.AetherStatus[q] = parseInt(Seed.resources[cityID]['rec5'][0] );
    }
    message += '%0A Total Aetherstone gain : '+addCommas(total)+'%0A';
    message += '%0A Total outgoing attacks : '+addCommas(totaldf)+'%0A';
   for (z in AttackOptions.ItemsFound){
      message += '%0A'+unsafeWindow.g_js_strings.commonstr.found+' '+unsafeWindow.ksoItems[z].name+' x '+AttackOptions.ItemsFound[z];
   }
    message += '%0A'+'%0A'+ 'Excess traffic errors: ' + AttackOptions.BarbsFailedTraffic +'%0A';
    message += 'Rallypoint errors: ' + AttackOptions.BarbsFailedRP +'%0A';
    message += 'Knight errors: ' + AttackOptions.BarbsFailedKnight +'%0A';
    message += 'Bog errors: ' + AttackOptions.BarbsFailedBog +'%0A';
    message += 'Other errors: ' + AttackOptions.BarbsFailedVaria +'%0A';
    message += 'Actual sent attacks: ' + (AttackOptions.BarbsTried - AttackOptions.BarbsFailedTraffic - AttackOptions.BarbsFailedRP - AttackOptions.BarbsFailedKnight -  AttackOptions.BarbsFailedVaria) +'%0A';
    params.message = message;  
    
    params.requestType = "COMPOSED_MAIL";
    new AjaxRequest(unsafeWindow.g_ajaxpath + "ajax/getEmail.php" + unsafeWindow.g_ajaxsuffix, {
        method: "post",
        parameters: params,
        onSuccess: function (message) {
            var rslt = eval("(" + message.responseText + ")");
            if (rslt.ok) {
               // Reset stats
               AttackOptions.LastReport = now;
               AttackOptions.BarbsFailedTraffic = 0;
               AttackOptions.BarbsFailedRP = 0;
               AttackOptions.BarbsFailedKnight = 0;
               AttackOptions.BarbsFailedBog = 0;
               AttackOptions.BarbsFailedVaria = 0;
               AttackOptions.BarbsTried = 0;
               AttackOptions.ItemsFound = {};
               for (q=1; q<=Seed.cities.length;q++){
                  AttackOptions.BarbsDone[q] = 0;
               }
               saveAttackOptions();
            } else {
            }
        },
        onFailure: function () {
        },
    });  
  },
  
  clickedSearch : function (){
    var t = Tabs.Barb;
    
    t.opt.maxDistance = parseInt(AttackOptions.MaxDistance);
    t.opt.searchDistance = (t.opt.maxDistance*2);
    if(t.opt.maxDistance > 40){
        t.opt.searchDistance = 40;
    }
    t.opt.searchShape = 'circle';
    t.mapDat = [];
    t.firstX =  t.opt.startX - t.opt.maxDistance;
    t.lastX = t.opt.startX + t.opt.maxDistance;
    t.firstY =  t.opt.startY - t.opt.maxDistance;
    t.lastY = t.opt.startY + t.opt.maxDistance;
    t.tilesSearched = 0;
    t.tilesFound = 0;
    t.curX = t.firstX;
    t.curY = t.firstY;
    var xxx = t.MapAjax.normalize(t.curX);
    var yyy = t.MapAjax.normalize(t.curY);
    var element = 'pddatacity'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ xxx +','+ yyy;
   var element2 = 'pddataarray'+(t.lookup-1);
   document.getElementById(element2).innerHTML == '';
    setTimeout (function(){t.MapAjax.request (xxx, yyy, t.opt.searchDistance, t.mapCallback)}, MAP_DELAY);
  },
  
  mapCallback : function (left, top, width, rslt){
    var t = Tabs.Barb;
    if (!t.searchRunning)
      return;
    if (rslt.ok){
    map = rslt.data;
    var cityID = 'city' + Seed.cities[t.lookup-1][0];
   var tiles = [];
    for(x in Seed.queue_atkp[cityID]) {
      tiles.push(Seed.queue_atkp[cityID][x].toTileId);
   }
   
    for (k in map){
      if (map[k].tileType==54 && AttackOptions.Levels[t.lookup][map[k].tileLevel]){
         var dist = distance (t.opt.startX, t.opt.startY, map[k].xCoord, map[k].yCoord);
         if(dist <= parseInt(AttackOptions.MaxDistance))
            if(dist <= parseInt(AttackOptions.Distance[map[k].tileLevel]))
            if(tiles.indexOf(map[k].tileId) == -1)
                t.mapDat.push ({time:0,x:map[k].xCoord,y:map[k].yCoord,dist:dist,level:map[k].tileLevel});
             //else logit('skipping '+map[k].xCoord+','+map[k].yCoord);
      }
    }
    
    
    t.tilesSearched += (t.opt.searchDistance*t.opt.searchDistance);

    t.curX += t.opt.searchDistance;
    if (t.curX > t.lastX){
      t.curX = t.firstX;
      t.curY += t.opt.searchDistance;
      if (t.curY > t.lastY){
        t.stopSearch('Found: ' + t.mapDat.length);
        return;
      }
    }
    var x = t.MapAjax.normalize(t.curX);
    var y = t.MapAjax.normalize(t.curY);
    
    
   var element0 = 'pdtotalcity'+(t.lookup-1);
   
    if (t.mapDat.length < 1) document.getElementById(element0).innerHTML = 'No Data';
        else document.getElementById(element0).innerHTML =  'Forests:' + t.mapDat.length;
    var element = 'pddatacity'+(t.lookup-1);
    document.getElementById(element).innerHTML = 'Searching at '+ x +','+ y;
    
    setTimeout (function(){t.MapAjax.request (x, y, t.opt.searchDistance, t.mapCallback)}, MAP_DELAY);
   } else {
      setTimeout (function(){t.MapAjax.request (left, top, t.opt.searchDistance, t.mapCallback)}, MAP_DELAY);
   }
    
  },
  
  stopSearch : function (msg){
    var t = Tabs.Barb;
    var element = 'pddatacity'+(t.lookup-1);
        document.getElementById(element).innerHTML = msg;
    GM_setValue('DF_' + Seed.player['name'] + '_city_' + t.lookup + '_' + getServerId(), JSON2.stringify(t.mapDat));
    AttackOptions.Update[t.lookup][0] = unixTime();
    AttackOptions.Update[t.lookup][1]++;
    t.searchRunning = false;
    saveAttackOptions();
    t.checkBarbData();
    return;
  },
  
  hide : function (){
  
  },

  show : function (){
  
  },

};
